package com.herench.bs.transfer;

import com.herench.bs.transfer.Dialect;
import com.herench.bs.utils.DataFormatUtils;
import org.apache.cxf.endpoint.Client;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.*;

/**
 * Created by ThinkPad on 2017/9/4.
 */
public class AppointScheduleTransfer extends AbstractTransfer {


    public AppointScheduleTransfer(String method, Client client, String messageMethod) {
        super(method, client,messageMethod);
    }


    @Override
    public String toInvokeMessage(Map<String, Object> params) throws Exception {
        Document document = getTplDoc(getMethod());
        Element dataRow = document.getRootElement().element("CommitData").addElement("Data").addElement("DataRow");
        String start = (String) params.get("start");
        start = start != null ? start : "";
        dataRow.addAttribute("CLINIC_DATE_START", start);
        String end = (String) params.get("end");
        end = end != null ? end : "";
        dataRow.addAttribute("CLINIC_DATE_END", end);
        String deptCode = (String) params.get("deptCode");
        deptCode = deptCode != null ? deptCode : "";
        dataRow.addAttribute("DEPT_CODE", deptCode);
        String doctorCode = (String) params.get("doctorCode");
        doctorCode = doctorCode != null ? doctorCode : "";
        dataRow.addAttribute("DOCTOR_CODE", doctorCode);
        return document.asXML();
    }

    @Override
    public Map<String, Object> toResultMessage(String resMsg) throws Exception {
        Map<String, Object> data = new HashMap<>(16);
        Map<String, Object> resMap = new HashMap<>(16);
        Document document = DocumentHelper.parseText(resMsg);
        Element resultInfo = document.getRootElement().element("Result").element("Info");
        String executeStatus = resultInfo.attributeValue("EXECUTE_STATUS");
        String executeMessage = resultInfo.attributeValue("EXECUTE_MESSAGE");
        if (Dialect.getSuccessfulState().equals(executeStatus)) {
            List<Map<String, Object>> resList = new ArrayList<>();
            List<Map<String, String>> schDateList = new ArrayList<>();
            TreeMap<String, String> tempSchDateTreeMap = new TreeMap<>();
            List<Element> dataRows = document.getRootElement().element("ReturnData").element("Data").elements();
            if (dataRows != null) {
                for (Element element : dataRows) {
                    /**
                     * 开始解析datarow
                     <DataRow CLINIC_LABEL="010140+董军" CLINIC_DATE="2017-09-06" TIME_DESC="上午" CLINIC_TYPE="主任"
                     APPOINTMENT_LIMITS="22" APPOINTMENT_NUM="0" REGIST_FEE="13.00" CLINIC_FEE="0.00" OTHER_FEE="0.00"
                     CLINIC_DEPT="010140" DEPT_NAME="心内科门诊" DOCTOR_CODE="0165" DOCTOR="董军"/>
                     */
                    AppointScheduleInnerMessage innerMessage = new AppointScheduleInnerMessage(element);
                    /**
                     * 定义号别map，用于分层显示专家、主任、副主任、普通号别类
                     */
                    Map<String, Object> categorMap = (Map<String, Object>) data.get(innerMessage.getClinicType());
                    if (categorMap == null) {
                        categorMap = new HashMap<>(16);
                        data.put(innerMessage.getClinicType(), categorMap);
                        categorMap.put("categorCode", Dialect.getClinicTypeCode(innerMessage.getClinicType()));
                    }
                    /**
                     * 定义排班列表list
                     */
                    List<Map<String, Object>> schemeList = (List<Map<String, Object>>) categorMap.get("schemeList");
                    if (schemeList == null) {
                        schemeList = new ArrayList<>();
                        categorMap.put("schemeList", schemeList);
                    }
                    Map<String, Object> el = new HashMap<>(16);
                    el.put("deptId", innerMessage.getClinicDept());
                    el.put("docId", innerMessage.getDoctorCode());
                    el.put("docName", innerMessage.getDoctor());
                    el.put("regFee", DataFormatUtils.getFormatMoney(Double.valueOf(innerMessage.getRegistFee()) + Double.valueOf(innerMessage.getClinicFee()) + Double.valueOf(innerMessage.getOtherFee())));
                    String schDate = DataFormatUtils.getSimpleDayString(innerMessage.clinicDate);
                    el.put("schDate", schDate);
                    tempSchDateTreeMap.put(schDate, innerMessage.clinicDate);
                    String schState = "0";
                    String schStateName = "可预约";
                    int remainingNumber = 0;
                    String appointmentLimitsStr = innerMessage.getAppointmentLimits();
                    String appointmentNumStr = innerMessage.getAppointmentNum();
                    if (!(appointmentLimitsStr == null || "".equals(appointmentLimitsStr) || appointmentNumStr == null || "".equals(appointmentNumStr))) {
                        int appointmentLimits = Integer.parseInt(appointmentLimitsStr);
                        int appointmentNum = Integer.parseInt(appointmentNumStr);
                        remainingNumber = appointmentLimits - appointmentNum;
                        if (remainingNumber < 0 || remainingNumber == 0) {
                            schState = "2";
                            schStateName = "约满";
                        }
                    }
                    el.put("schState", schState);
                    el.put("schStateName", schStateName);
                    el.put("numCount", appointmentLimitsStr);
                    el.put("numRemain", Integer.toString(remainingNumber));
                    schemeList.add(el);
                }
            }
            for (Map.Entry<String, String> entry : tempSchDateTreeMap.entrySet()) {
                Map<String, String> dateMap = new HashMap<>(16);
                dateMap.put("key", entry.getKey());
                String key1 = DataFormatUtils.getSimpleDay1String(entry.getValue());
                dateMap.put("key1", key1);
                dateMap.put("value", entry.getValue());
                String text = DataFormatUtils.getWeekOfDate(DataFormatUtils.parserDay(entry.getValue()));
                String text1 = DataFormatUtils.getWeekOfDate1(DataFormatUtils.parserDay(entry.getValue()));
                dateMap.put("text", text);
                dateMap.put("text1", text1);
                schDateList.add(dateMap);
            }

            for (Map.Entry<String, Object> entry : data.entrySet()) {
                Map<String, Object> categorMap = (Map<String, Object>) entry.getValue();
                List<Map<String, Object>> schemeList = (List<Map<String, Object>>) categorMap.get("schemeList");
                if (schemeList != null) {
                    List<Map<String, Object>> newTempList = new ArrayList<>();
                    Map<String, Object> elMap = new HashMap<>(16);
                    elMap.put("schemeList", newTempList);
                    elMap.put("categorCode", Dialect.getClinicTypeCode(entry.getKey()));
                    elMap.put("categorName", entry.getKey());
                    resList.add(elMap);
                    Collections.sort(schemeList, new Comparator<Map<String, Object>>() {
                        @Override
                        public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                            return o1.get("docId").toString().compareTo(o2.get("docId").toString());
                        }
                    });
                    Map<String, Object> guard = null;
                    for (Map<String, Object> tempMap : schemeList) {
                        if (guard == null) {
                            guard = tempMap;
                            newTempList.add(guard);
                        } else {
                            if (guard.get("docId").equals(tempMap.get("docId"))) {
                                guard.put("schDate", guard.get("schDate") + " " + tempMap.get("schDate"));
                            } else {
                                guard = tempMap;
                                newTempList.add(guard);
                            }
                        }
                        List<Map<String, Object>> subSchDateList = (List<Map<String, Object>>) guard.get("subSchDateList");
                        if (subSchDateList == null) {
                            subSchDateList = new ArrayList<>();
                            guard.put("subSchDateList", subSchDateList);
                        }
                        String tempSchDate = tempSchDateTreeMap.get(tempMap.get("schDate"));
                        Map<String, Object> tempEl = new HashMap<>(16);
                        tempEl.put("key", (String) tempMap.get("schDate"));
                        tempEl.put("value", tempSchDate);
                        subSchDateList.add(tempEl);
                        for (Map<String, Object> map : subSchDateList){
                            List<Map<String, Object>> list = (List<Map<String, Object>>)map.get("schemeList");
                            if (list != null && list.size() > 1) {
                                list.remove(1);
                            }
                        }
                    }
                }
            }
            Collections.sort(resList, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    return o1.get("categorCode").toString().compareTo(o2.get("categorCode").toString());
                }
            });

            resMap.put("data", resList);
            resMap.put("schDateList", schDateList);
            return resMap;
        } else {
            resMap.put("code", executeMessage);
            resMap.put("message", executeMessage);
            return resMap;
        }
    }


    private class AppointScheduleInnerMessage implements InnerMessage {
        /**
         * 号表名称
         */
        private String clinicLabel;
        /**
         * 出诊日期
         */
        private String clinicDate;
        /**
         * 时段
         */
        private String timeDesc;
        /**
         * 号别
         */
        private String clinicType;
        /**
         * 预约限号数
         */
        private String appointmentLimits;
        /**
         * 已预约数
         */
        private String appointmentNum;
        /**
         * 挂号费
         */
        private String registFee;
        /**
         * 诊查费
         */
        private String clinicFee;
        /**
         * 其他费用
         */
        private String otherFee;
        /**
         * 科室
         */
        private String clinicDept;
        /**
         * 科室名
         */
        private String deptName;
        /**
         * 医生代码
         */
        private String doctorCode;
        /**
         * 医生名
         */
        private String doctor;


        public AppointScheduleInnerMessage(Element element) {
            this.clinicLabel = element.attributeValue("CLINIC_LABEL");
            this.clinicDate = element.attributeValue("CLINIC_DATE");
            this.timeDesc = element.attributeValue("TIME_DESC");
            this.clinicType = element.attributeValue("CLINIC_TYPE");
            this.appointmentLimits = element.attributeValue("APPOINTMENT_LIMITS");
            this.appointmentNum = element.attributeValue("APPOINTMENT_NUM");
            this.registFee = element.attributeValue("REGIST_FEE");
            this.clinicFee = element.attributeValue("CLINIC_FEE");
            this.otherFee = element.attributeValue("OTHER_FEE");
            this.clinicDept = element.attributeValue("CLINIC_DEPT");
            this.deptName = element.attributeValue("DEPT_NAME");
            this.doctorCode = element.attributeValue("DOCTOR_CODE");
            this.doctor = element.attributeValue("DOCTOR");
        }

        public String getClinicLabel() {
            return clinicLabel;
        }

        public void setClinicLabel(String clinicLabel) {
            this.clinicLabel = clinicLabel;
        }

        public String getClinicDate() {
            return clinicDate;
        }

        public void setClinicDate(String clinicDate) {
            this.clinicDate = clinicDate;
        }

        public String getTimeDesc() {
            return timeDesc;
        }

        public void setTimeDesc(String timeDesc) {
            this.timeDesc = timeDesc;
        }

        public String getClinicType() {
            return clinicType;
        }

        public void setClinicType(String clinicType) {
            this.clinicType = clinicType;
        }

        public String getAppointmentLimits() {
            return appointmentLimits;
        }

        public void setAppointmentLimits(String appointmentLimits) {
            this.appointmentLimits = appointmentLimits;
        }

        public String getAppointmentNum() {
            return appointmentNum;
        }

        public void setAppointmentNum(String appointmentNum) {
            this.appointmentNum = appointmentNum;
        }

        public String getRegistFee() {
            return registFee;
        }

        public void setRegistFee(String registFee) {
            this.registFee = registFee;
        }

        public String getClinicFee() {
            return clinicFee;
        }

        public void setClinicFee(String clinicFee) {
            this.clinicFee = clinicFee;
        }

        public String getOtherFee() {
            return otherFee;
        }

        public void setOtherFee(String otherFee) {
            this.otherFee = otherFee;
        }

        public String getClinicDept() {
            return clinicDept;
        }

        public void setClinicDept(String clinicDept) {
            this.clinicDept = clinicDept;
        }

        public String getDeptName() {
            return deptName;
        }

        public void setDeptName(String deptName) {
            this.deptName = deptName;
        }

        public String getDoctorCode() {
            return doctorCode;
        }

        public void setDoctorCode(String doctorCode) {
            this.doctorCode = doctorCode;
        }

        public String getDoctor() {
            return doctor;
        }

        public void setDoctor(String doctor) {
            this.doctor = doctor;
        }
    }

}
